module demo (
    input           clk,                 //时钟信号
    input           rst_n,               //复位信号
    input   [3:0]   i_data,              //创建四位输入端口i_data
    input   [3:0]   q_data,              //创建四位输入端口q_data
    input           ready_in,            //创建输入端口ready_in
    input   [1:0]   sel,                 //创建两位输入端口sel
    output  [4:0]   out_data,            //创建五位输出端口out_data
    output          ready_out            
);

    reg [3:0] i_data_reg;               //四位对应输入端口的寄存器           
    reg [3:0] q_data_reg;               //四位对应输入端口的寄存器           
    reg [3:0] out_data_reg;             //四位对应输出端口的寄存器           

    reg [3:0] cnt;                      //四位用来计数的寄存器

    //计数器
    //当时钟信号上升或复位信号下降时运作 复位信号为0或计数器到8清零计数器 否则计数加一 
    always @(posedge clk or negedge rst_n) begin    
        if(!rst_n)                            
            cnt<=4'b0;
        
        else if(cnt==4'd8)         
            cnt<=4'b0;
        
        else            
            cnt<=cnt+1'b1;
    end

    //reg in
    //当时钟信号上升或复位信号下降时运作 复位信号信号为0时清零i与q输入端口对应的寄存器  计数到四 分别给寄存器赋值为3  ready_in为真时 将i_data与q_data对应的值放入寄存器
    always @(posedge clk or negedge rst_n) begin   
        if(!rst_n)                
            i_data_reg<=4'd0;           
        else if(cnt==4'd4)           
            i_data_reg<=4'd3;
        else if(ready_in)           
            i_data_reg<=i_data;
    end
    always @(posedge clk or negedge rst_n) begin   
        if(!rst_n)              
            q_data_reg<=4'd0;
        else if(cnt==4'd4)  
            q_data_reg<=4'd3;
        else if(ready_in)     
            q_data_reg<=q_data;
    end  

//-------------------------------------写法1------------------------------------------//
/*
    //MUX
    always @(*) begin
        case (sel)
            2'b00:  out_data_reg = i_data_reg;
            2'b01:  out_data_reg = i_data_reg * q_data_reg;
            2'b10:  out_data_reg = i_data_reg & q_data_reg;
            2'b11:  out_data_reg = i_data_reg && q_data_reg;
            default:;
        endcase
    end

    assign out_data = out_data_reg;
    assign ready_out = ready_in;
*/

//-------------------------------------写法2------------------------------------------//

    //MUX
    //sel为00时 给out_data赋值i_data_reg  
    //sel为01时 给out_data赋值i_data_reg * q_data_reg  
    //sel为10时 给out_data赋值i_data_reg & q_data_reg  
    //若都不是则赋值i_data_reg && q_data_reg
    assign out_data = (sel==2'b00) ?  i_data_reg : 
                      (sel==2'b01) ? (i_data_reg * q_data_reg) :
                      (sel==2'b10) ? (i_data_reg & q_data_reg) :
                                     (i_data_reg && q_data_reg); 
    assign ready_out = ready_in;       //给ready_out 赋值 ready_in的值

endmodule